package cc.csln.so.cdelayqueue;

import java.util.UUID;
import java.util.function.BiConsumer;

public interface IDelayQueue {

    long getDefaultDelayMs();

    /**
     * 使用默认延迟（配置中的 delayMs）添加任务，自动生成随机 key。
     *
     * @param callback 任务触发时调用，形参为 key 与 payload
     */
    default void addTask(BiConsumer<String, String> callback) {
        addTask(getDefaultDelayMs(), callback);
    }

    /**
     * 使用默认延迟添加任务，指定任务 key，无 payload。
     *
     * @param key      任务唯一标识（去重依据）
     * @param callback 任务触发时调用
     */
    default void addTask(String key, BiConsumer<String, String> callback) {
        addTask(key, null, getDefaultDelayMs(), callback);
    }

    /**
     * 指定延迟毫秒添加任务，自动生成随机 key，无 payload。
     *
     * @param delayMs  延迟毫秒
     * @param callback 任务触发时调用
     */
    default void addTask(long delayMs, BiConsumer<String, String> callback) {
        addTask(UUID.randomUUID().toString(), null, delayMs, callback);
    }

    /**
     * 指定 key 与延迟毫秒添加任务，无 payload。
     *
     * @param key      任务 key
     * @param delayMs  延迟毫秒
     * @param callback 任务触发时调用
     */
    default void addTask(String key, long delayMs, BiConsumer<String, String> callback) {
        addTask(key, null, delayMs, callback);
    }

    /**
     * 指定 key 与 payload，使用默认延迟添加任务。
     *
     * @param key      任务 key
     * @param payload  任务负载（透传给回调）
     * @param callback 任务触发时调用
     */
    default void addTask(String key, String payload, BiConsumer<String, String> callback) {
        addTask(key, payload, getDefaultDelayMs(), callback);
    }

    /**
     * 新增或刷新延迟任务（按 key 去重），支持任务级回调。
     * <p>
     * 逻辑：
     * - 当 key 已存在时：从队列移除旧任务，刷新触发时间、负载与回调，再重新入队
     * - 当 key 不存在时：创建新任务、记录映射并入队
     * <p>
     * 线程安全：使用 synchronized(this) 保证映射与队列操作的一致性。
     *
     * @param key      任务 key，不可为空或空白
     * @param payload  任务负载，可为空
     * @param delayMs  延迟毫秒，>=0
     * @param callback 任务触发时调用，不能为空
     */
    void addTask(String key, String payload, long delayMs, BiConsumer<String, String> callback);
}
